package com.yrline.pay.util.httpclient;

import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;

import javax.net.ssl.SSLContext;

import org.apache.http.HttpException;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.auth.AuthScope;
import org.apache.http.client.CookieStore;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.protocol.HttpContext;


/**
 * 
 * @author fanrui
 *
 */
public class ElideHttpClientGenerator {


    private PoolingHttpClientConnectionManager connectionManager;

    public ElideHttpClientGenerator() {
    	SSLContext sslContext = null;
    	try {
    	  sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
			
			@Override
			public boolean isTrusted(X509Certificate[] arg0, String arg1)
					throws CertificateException {
				// TODO Auto-generated method stub
				return true;
			}
		}).build();
    	} catch (Exception e) {
    	  throw new RuntimeException("can not create http client.", e);
    	}
    	SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext);
        Registry<ConnectionSocketFactory> reg = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.INSTANCE)
                .register("https", sslSocketFactory)
                .build();
        connectionManager = new PoolingHttpClientConnectionManager(reg);
        connectionManager.setDefaultMaxPerRoute(100);

               
    }

    public ElideHttpClientGenerator setPoolSize(int poolSize) {
        connectionManager.setMaxTotal(poolSize);
        return this;
    }

    public CloseableHttpClient getClient(Site site) {
        return generateClient(site);
    }

    private CloseableHttpClient generateClient(Site site) {
    	if(site.getSslContextFactory() !=null){
    		 Registry<ConnectionSocketFactory> reg = RegistryBuilder.<ConnectionSocketFactory>create()
    	                .register("http", PlainConnectionSocketFactory.INSTANCE)
    	                .register("https",site.getSslContextFactory())
    	                .build();
    		 connectionManager = new PoolingHttpClientConnectionManager(reg);
    	        connectionManager.setDefaultMaxPerRoute(50);
    	}
        HttpClientBuilder httpClientBuilder = HttpClients.custom().setConnectionManager(connectionManager);
        if (site != null && site.getUserAgent() != null) {
            httpClientBuilder.setUserAgent(site.getUserAgent());
        } else {
            httpClientBuilder.setUserAgent("");
        }
        if (site == null || site.isUseGzip()) {
            httpClientBuilder.addInterceptorFirst(new HttpRequestInterceptor() {

                public void process(
                        final HttpRequest request,
                        final HttpContext context) throws HttpException, IOException {
                    if (!request.containsHeader("Accept-Encoding")) {
                        request.addHeader("Accept-Encoding", "gzip");
                    }

                }
            });
        }
        SocketConfig socketConfig = SocketConfig.custom().setSoKeepAlive(true).setTcpNoDelay(true).build();
        httpClientBuilder.setDefaultSocketConfig(socketConfig);
        if (site != null) {
            httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(site.getRetryTimes(), true));
        }
        if(site.isEnableProxy()){
        	httpClientBuilder.setProxy(new HttpHost("192.168.31.174", 8888));
        }
        
     //   generateCookie(httpClientBuilder, site);
       return  httpClientBuilder.build();
        
    }

//    private void generateCookie(HttpClientBuilder httpClientBuilder, Site site) {
//        CookieStore cookieStore = new BasicCookieStore();
//        for (Map.Entry<String, String> cookieEntry : site.getCookies().entrySet()) {
//            BasicClientCookie cookie = new BasicClientCookie(cookieEntry.getKey(), cookieEntry.getValue());
//            cookie.setDomain(site.getDomain());
//            cookieStore.addCookie(cookie);
//        }
//        for (Map.Entry<String, Map<String, String>> domainEntry : site.getAllCookies().entrySet()) {
//            for (Map.Entry<String, String> cookieEntry : domainEntry.getValue().entrySet()) {
//                BasicClientCookie cookie = new BasicClientCookie(cookieEntry.getKey(), cookieEntry.getValue());
//                cookie.setDomain(domainEntry.getKey());
//                cookieStore.addCookie(cookie);
//            }
//        }
//        httpClientBuilder.setDefaultCookieStore(cookieStore);
//    }
}
